package edu.hawaii.duedates.libraries;

import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import java.util.ArrayList;
import org.xml.sax.SAXException;
import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.HttpUnitOptions;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;
import edu.hawaii.duedates.BorrowedItem;
import edu.hawaii.duedates.LenderQuery;

/**
 * UH Manoa Library class. Contains all the necessary methods to log in and retrieve the borrowed
 * items from the library system.
 * 
 * @author Daniel Tian, Aric West
 */
public class UhManoaLibraryQuery extends LenderQuery {
  WebConversation conversation;
  private final String url;

  /**
   * Constructor. Assigns the number of fields this class expects, the full library name, and
   * instantiates the ArrayList object used to store the list of borrowed items.
   */
  public UhManoaLibraryQuery() {
    this.expectedNumberOfFields = 2;
    this.lenderName = "University of Hawaii at Manoa";
    this.itemList = new ArrayList<BorrowedItem>();
    this.conversation = new WebConversation();
    this.url = "http://uhmanoa.lib.hawaii.edu/cgi-bin/Pwebrecon.cgi?DB=local&PAGE=pbLogon";
  }

  /**
   * Attempts to login to UH Manoa Library system. Code modified from
   * 
   * @param fieldList a List of the fields this class needs to log into the lender system
   * @return conversation a WebConversation instance after successful login
   */
  public boolean logIn(List<String> fieldList) {

    if (fieldList.size() == this.expectedNumberOfFields) {
      try {
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);
        
        WebRequest request = new GetMethodWebRequest(this.url);
        WebResponse response = this.conversation.getResponse(request);

        WebForm form = response.getFormWithName("logonpage");

        form.setParameter("BC", fieldList.get(0));
        form.setParameter("LN", fieldList.get(1));
        form.submit();
        response = this.conversation.getCurrentPage();

        if (!response.getText().contains("Sorry, Login unsuccessful.")) {
          return true;
        }
      }
      catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }

    return false;
  }

  /**
   * Logs the user into the system and gets a list of their borrowed items.
   * 
   * @return itemList an ArrayList of all the borrowed items from this lender
   */
  public boolean parseBorrowedItems() {
    try {
      WebResponse response = this.conversation.getCurrentPage();
      WebTable table;
      
      if (!response.getText().contains("You have no items checked out.")) {
        if (response.getText().contains("Renew?")) {
          table = response.getTableStartingWith("Renew?");
        }
        else {
          table = response.getTableStartingWith("Item");
        }
        
        List<String> fieldList = new ArrayList<String>();
        BorrowedItem item;
  
        for (int i = 1; i < table.getRowCount(); i++) {
          if (table.getCellAsText(i, 1).equals("Total Amount Due")) {
            break;
          }
          else {
            if (response.getText().contains("Renew?")) {
              fieldList.add(table.getCellAsText(i, 1));
              fieldList.add(table.getCellAsText(i, 3));
            }
            else {
              fieldList.add(table.getCellAsText(i, 0));
              fieldList.add(table.getCellAsText(i, 2));
            }
            
            fieldList.add(this.lenderName);
            item = new BorrowedItem(fieldList);
            this.itemList.add(item);
            fieldList.clear();
          }
        }
      return true; 
      }
    }
    catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    catch (SAXException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    catch (ParseException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    
    return false;
  }

  /**
   * Checks that a compared object is this type they have the same name and item list.
   * Also should later check for equality of id and last name.
   * 
   * @param o object
   * @return boolean value
   */
  public boolean equals(Object o) {
    return o != null 
        && this.getClass().equals(o.getClass())
        && this.lenderName.equals( ((UhManoaLibraryQuery) o).getLenderName() )
        && this.itemList.equals( ((UhManoaLibraryQuery) o).getItemList() );
  }

  /**
   * Calculates a hashcode for this object based on size of book list and expected parameters size.
   * Should use the id number later.
   * 
   * @return A hash value based on the due date of the item.
   */
  public int hashCode() {
    int hash = 7;
    int listSize = Integer.valueOf(this.itemList.size());
    hash = hash + ((listSize + this.expectedNumberOfFields) * 31);
    return hash;
  }
}
